package com.eduagent.xwqeduagent.app.agent;

import com.eduagent.xwqeduagent.constant.FileConstant;
import com.eduagent.xwqeduagent.model.vo.TeachingImprovementResultVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;

import cn.hutool.core.util.ObjectUtil;

/**
 * 教学指导专家
 * 负责分析教师教学情况、整合多方反馈、提供教学改进建议和资源推荐
 */
@Slf4j
@Component
public class TeachingGuidanceExpert {

    /**
     * 提供教学改进指导
     * @param userQuestion 用户提问内容
     * @param userId 用户ID
     * @param sessionId 会话ID
     * @param attachment 上传的附件（如课堂录像、教案等）
     * @return 教学改进指导结果
     */
    public TeachingImprovementResultVO provideTeachingGuidance(
            String userQuestion,
            String userId, 
            String sessionId, 
            MultipartFile attachment) {
        
        log.info("开始教学改进分析，用户提问：{}，用户ID：{}，附件名称：{}", 
                userQuestion != null ? (userQuestion.length() > 100 ? userQuestion.substring(0, 100) + "..." : userQuestion) : "无内容",
                userId,
                attachment != null ? attachment.getOriginalFilename() : "无附件");

        // 验证参数
        if (ObjectUtil.isEmpty(userQuestion) && attachment == null) {
            return TeachingImprovementResultVO.builder()
                    .status("error")
                    .message("用户提问和附件不能同时为空")
                    .build();
        }

        // Coze API配置
        String cozeApiUrl = "https://api.coze.cn/v3/chat";
        String botId = "7514260284710649908"; // 教学指导专家的botId
        String apiKey = "pat_qm2xo8JAVOw7DGJcgmbpMTENCEst9IBcMt2xxRKig1RJLH9QBHDeEq6jgb2rKCxj"; // API密钥

        try {
            // 构建请求体
            cn.hutool.json.JSONObject requestBody = new cn.hutool.json.JSONObject();
            requestBody.set("bot_id", botId);
            requestBody.set("user_id", userId);
            requestBody.set("stream", false);
            requestBody.set("auto_save_history", true);

            // 上传附件文件到Coze获取fileId
            String fileId = null;
            if (attachment != null && !attachment.isEmpty()) {
                try {
                    // 保存上传的文件到临时目录
                    String uploadDir = FileConstant.FILE_SAVE_DIR + "/teaching_improvement/";
                    cn.hutool.core.io.FileUtil.mkdir(uploadDir);
                    
                    String tempFilePath = uploadDir + sessionId + "_" + attachment.getOriginalFilename();
                    File tempFile = new File(tempFilePath);
                    attachment.transferTo(tempFile);
                    
                    // 上传到Coze API获取fileId
                    fileId = uploadFileToCaze(tempFile, apiKey);
                    log.info("附件[{}]上传到Coze成功，fileId: {}", attachment.getOriginalFilename(), fileId);
                } catch (Exception e) {
                    log.error("处理上传附件失败", e);
                    return TeachingImprovementResultVO.builder()
                            .status("error")
                            .message("附件上传到Coze失败：" + e.getMessage())
                            .build();
                }
            }

            // 构建消息内容
            cn.hutool.json.JSONArray additionalMessages = new cn.hutool.json.JSONArray();
            cn.hutool.json.JSONObject message = new cn.hutool.json.JSONObject();
            message.set("role", "user");
            
            // 如果有上传文件，使用对象格式
            if (fileId != null) {
                // 构建包含文件的消息内容
                cn.hutool.json.JSONArray objectContent = new cn.hutool.json.JSONArray();
                
                // 添加文件对象
                cn.hutool.json.JSONObject fileObj = new cn.hutool.json.JSONObject();
                fileObj.set("type", getFileTypeForCoze(attachment.getOriginalFilename()));
                fileObj.set("file_id", fileId);
                objectContent.add(fileObj);
                
                // 添加文本对象
                cn.hutool.json.JSONObject textObj = new cn.hutool.json.JSONObject();
                textObj.set("type", "text");
                
                // 构建提示词
                StringBuilder prompt = new StringBuilder("作为教学指导专家，请分析以下教学信息，提供个性化教学改进建议和资源推荐：");
                
                if (userQuestion != null && !userQuestion.trim().isEmpty()) {
                    prompt.append("\n\n【用户提问】\n").append(userQuestion);
                }
                
                prompt.append("\n\n请基于上述信息和附件，从教学模式、教学策略、课堂互动、教学资源等方面提供深入分析。请结合教育学理论，给出具体可行的教学改进建议，并推荐2-3篇相关教育研究论文和1-2个优秀教学案例视频。");
                
                textObj.set("text", prompt.toString());
                objectContent.add(textObj);
                
                message.set("content", objectContent.toString());
                message.set("content_type", "object_string");
            } else {
                // 无文件，使用普通文本格式
                StringBuilder prompt = new StringBuilder("作为教学指导专家，请分析以下教学信息，提供个性化教学改进建议和资源推荐：");
                
                if (userQuestion != null && !userQuestion.trim().isEmpty()) {
                    prompt.append("\n\n【用户提问】\n").append(userQuestion);
                }
                
                prompt.append("\n\n请基于上述信息，从教学模式、教学策略、课堂互动、教学资源等方面提供深入分析。请结合教育学理论，给出具体可行的教学改进建议，并推荐2-3篇相关教育研究论文和1-2个优秀教学案例视频。");
                
                message.set("content", prompt.toString());
                message.set("content_type", "text");
            }
            
            additionalMessages.add(message);
            requestBody.set("additional_messages", additionalMessages);

            // 设置请求头
            HashMap<String, String> headers = new HashMap<>();
            headers.put("Authorization", "Bearer " + apiKey);
            headers.put("Content-Type", "application/json");

            // 发送HTTP请求
            String result = cn.hutool.http.HttpUtil.createPost(cozeApiUrl)
                    .headerMap(headers, true)
                    .body(requestBody.toString())
                    .execute()
                    .body();

            log.info("教学改进分析请求已发送，初步响应：{}", result);

            // 解析响应
            cn.hutool.json.JSONObject responseJson = new cn.hutool.json.JSONObject(result);

            // 检查状态
            if (responseJson.containsKey("data") && responseJson.getJSONObject("data").containsKey("status")) {
                String status = responseJson.getJSONObject("data").getStr("status");
                String conversationId = responseJson.getJSONObject("data").getStr("conversation_id");
                String chatId = responseJson.getJSONObject("data").getStr("id");

                if ("in_progress".equals(status)) {
                    // 如果状态是"in_progress"，需要轮询获取结果
                    return pollForTeachingImprovementResult(conversationId, botId, apiKey, chatId);
                } else if ("completed".equals(status)) {
                    // 如果已完成，直接处理结果
                    return processTeachingImprovementResult(responseJson, sessionId);
                } else {
                    // 其他状态处理
                    log.warn("教学改进分析状态未知：{}", status);
                    return TeachingImprovementResultVO.builder()
                            .status("error")
                            .message("教学改进分析状态未知：" + status)
                            .build();
                }
            } else {
                // 保存原始响应
                String resultPath = FileConstant.FILE_SAVE_DIR + "/teaching_improvement/" + sessionId + "_raw.json";
                cn.hutool.core.io.FileUtil.writeString(result, resultPath, "UTF-8");

                return TeachingImprovementResultVO.builder()
                        .status("error")
                        .message("教学改进分析请求已提交，但响应格式不符合预期，已保存原始响应到：" + resultPath)
                        .build();
            }
        } catch (Exception e) {
            log.error("教学改进分析失败", e);

            return TeachingImprovementResultVO.builder()
                    .status("error")
                    .message("教学改进分析失败：" + e.getMessage())
                    .build();
        }
    }
    
    /**
     * 上传文件到Coze API
     * @param file 要上传的文件
     * @param apiKey API密钥
     * @return 文件ID
     */
    private String uploadFileToCaze(File file, String apiKey) throws IOException {
        String uploadUrl = "https://api.coze.cn/v1/files/upload";
        
        // 使用Hutool的HttpUtil上传文件
        HashMap<String, Object> paramMap = new HashMap<>();
        paramMap.put("file", file);
        
        HashMap<String, String> headers = new HashMap<>();
        headers.put("Authorization", "Bearer " + apiKey);
        
        String result = cn.hutool.http.HttpUtil.createPost(uploadUrl)
                .headerMap(headers, true)
                .form(paramMap)
                .execute()
                .body();
        
        // 解析响应获取文件ID
        cn.hutool.json.JSONObject jsonResult = new cn.hutool.json.JSONObject(result);
        if (jsonResult.getInt("code") == 0 && jsonResult.containsKey("data")) {
            return jsonResult.getJSONObject("data").getStr("id");
        } else {
            throw new IOException("上传文件到Coze失败: " + jsonResult.getStr("msg"));
        }
    }
    
    /**
     * 根据文件名确定Coze API的文件类型
     * @param fileName 文件名
     * @return 文件类型
     */
    private String getFileTypeForCoze(String fileName) {
        if (fileName == null) {
            return "file";
        }
        
        String extension = fileName.substring(fileName.lastIndexOf(".") + 1).toLowerCase();
        
        // 文档类型
        if (extension.equals("doc") || extension.equals("docx") || 
            extension.equals("xls") || extension.equals("xlsx") || 
            extension.equals("ppt") || extension.equals("pptx") || 
            extension.equals("pdf") || extension.equals("csv")) {
            return "file";
        }
        
        // 图片类型
        if (extension.equals("jpg") || extension.equals("jpeg") || 
            extension.equals("png") || extension.equals("gif") || 
            extension.equals("webp") || extension.equals("bmp")) {
            return "image";
        }
        
        // 音频类型
        if (extension.equals("mp3") || extension.equals("wav") || 
            extension.equals("m4a") || extension.equals("flac")) {
            return "audio";
        }
        
        // 视频类型
        if (extension.equals("mp4") || extension.equals("avi") || 
            extension.equals("mov") || extension.equals("mkv")) {
            return "video";
        }
        
        // 默认为普通文件
        return "file";
    }

    /**
     * 轮询获取教学改进分析结果
     */
    private TeachingImprovementResultVO pollForTeachingImprovementResult(String conversationId, String botId, String apiKey, String chatId) {
        // 构造API地址
        String checkStatusUrl = "https://api.coze.cn/v3/chat/message/list?" +
                "chat_id=" + chatId +
                "&conversation_id=" + conversationId;

        // 请求头配置
        HashMap<String, String> headers = new HashMap<>();
        headers.put("Authorization", "Bearer " + apiKey);
        headers.put("Content-Type", "application/json");

        // 最多尝试20次，每次间隔3秒
        for (int i = 0; i < 20; i++) {
            try {
                Thread.sleep(6000);
                String result = cn.hutool.http.HttpUtil.createGet(checkStatusUrl)
                        .headerMap(headers, true)
                        .execute()
                        .body();

                log.info("轮询教学改进分析状态，第{}次尝试，结果: {}", (i+1), result.substring(0, Math.min(500, result.length())));
                cn.hutool.json.JSONObject responseJson = new cn.hutool.json.JSONObject(result);

                // 检查响应状态码
                if (responseJson.getInt("code") == 0) {
                    // 检查是否有data字段且为数组
                    if (responseJson.containsKey("data") && responseJson.get("data") instanceof cn.hutool.json.JSONArray) {
                        // 获取消息列表
                        cn.hutool.json.JSONArray messages = responseJson.getJSONArray("data");
                        if (messages.isEmpty()) {
                            log.info("轮询结果中消息列表为空，继续等待...");
                            continue;
                        }

                        // 遍历消息找到bot_response类型的消息
                        for (int j = 0; j < messages.size(); j++) {
                            cn.hutool.json.JSONObject message = messages.getJSONObject(j);
                            String type = message.getStr("type");
                            if ("answer".equals(type)) {
                                String content = message.getStr("content");
                                if (content != null && !content.isEmpty()) {
                                    // 检查是否为工具调用消息
                                    if (content.contains("\"name\":\"") && content.contains("\"arguments\":")) {
                                        log.info("收到工具调用消息，继续等待实际回复...");
                                        continue; // 跳过工具调用消息，继续查找实际内容
                                    }
                                    // 处理真正的内容
                                    return processTeachingImprovementResult(message, chatId);
                                }
                            }
                        }
                        log.info("未找到教学改进分析结果消息，继续等待...");
                    } else {
                        // 如果没有data数组，可能是因为分析仍在进行中
                        if (responseJson.containsKey("msg") && !responseJson.getStr("msg").isEmpty()) {
                            log.info("教学改进分析中，继续等待: {}", responseJson.getStr("msg"));
                        } else {
                            log.info("教学改进分析中，继续等待...");
                        }
                    }
                } else {
                    // 非零状态码，表示有错误
                    String errorMsg = responseJson.getStr("msg");
                    log.warn("轮询教学改进分析遇到错误，状态码: {}, 错误信息: {}", responseJson.getInt("code"), errorMsg);
                    
                    if (i >= 10) {  // 如果已经尝试了超过10次，返回错误
                        return TeachingImprovementResultVO.builder()
                                .status("error")
                                .message("教学改进分析遇到错误: " + errorMsg)
                                .build();
                    }
                }
            } catch (Exception e) {
                log.error("轮询教学改进分析状态出现异常", e);
            }
        }

        // 所有尝试失败后，直接获取最终结果尝试一次
        try {
            String chatUrl = "https://api.coze.cn/v3/chat/messages?id=" + chatId;
            String finalResult = cn.hutool.http.HttpUtil.createGet(chatUrl)
                    .headerMap(headers, true)
                    .execute()
                    .body();
            
            log.info("尝试获取最终分析结果: {}", finalResult.substring(0, Math.min(500, finalResult.length())));
            cn.hutool.json.JSONObject finalJson = new cn.hutool.json.JSONObject(finalResult);
            
            if (finalJson.getInt("code") == 0 && finalJson.containsKey("data")) {
                cn.hutool.json.JSONObject data = finalJson.getJSONObject("data");
                if (data.containsKey("content")) {
                    String content = data.getStr("content");
                    if (content != null && !content.isEmpty()) {
                        return TeachingImprovementResultVO.builder()
                                .status("success")
                                .improvementAdvice(content)
                                .message("成功获取教学改进建议")
                                .build();
                    }
                }
            }
        } catch (Exception e) {
            log.error("获取最终结果失败", e);
        }

        return TeachingImprovementResultVO.builder()
                .status("error")
                .message("教学改进分析超时，请稍后再试")
                .build();
    }

    /**
     * 处理教学改进分析结果
     * @param messageJson 消息JSON
     * @param sessionId 会话ID
     * @return 教学改进结果
     */
    private TeachingImprovementResultVO processTeachingImprovementResult(cn.hutool.json.JSONObject messageJson, String sessionId) {
        try {
            // 从消息中提取content字段
            String content = messageJson.getStr("content");
            if (cn.hutool.core.util.StrUtil.isBlank(content)) {
                throw new IllegalArgumentException("消息中缺少content字段");
            }

            log.info("原始教学改进分析内容，长度: {}", content.length());
            
            // 提取教学改进建议
            String improvementAdvice = content;

            // 直接返回结果
            return TeachingImprovementResultVO.builder()
                    .status("success")
                    .message("成功")
                    .improvementAdvice(improvementAdvice)
                    .build();
        } catch (Exception e) {
            // 异常处理
            String errorMessage = "处理教学改进分析结果失败";
            if (e instanceof IllegalArgumentException) {
                log.warn("{}：{}", errorMessage, e.getMessage());
                return TeachingImprovementResultVO.builder()
                        .status("error")
                        .message(errorMessage)
                        .build();
            } else {
                log.error(errorMessage, e);
                return TeachingImprovementResultVO.builder()
                        .status("error")
                        .message(errorMessage + "：" + e.getClass().getSimpleName())
                        .build();
            }
        }
    }
} 